package com.hundsun.yr.universal.p2p.widget;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;

import com.hundsun.mobile.zwgt.R;

/**
 * Created by xx on 2017/8/8.
 * 1、添加xml文件属性设置
 * 2、添加监听
 * 3、添加动画
 * 4、添加所有控件宽高设置
 */

public class HSProgressButton extends View {
    private Paint mRedPaint;
    private Paint mGrayPaint;
    private float currentProgress = 0;
    private RectF mOval1;
    private RectF mOval2;
    private RectF mOvalProgress1;
    private RectF mOvalProgress2;
    private Paint textPaint;
    private Path mProgressPath;

    /**
     * 半圆的周长
     */
    private float mPerimeter;

    /**
     * 设置线的宽度
     */
    private int strokeWidth = 5;//设置线的宽度

    /**
     * 设置半圆的半径
     */
    private float radius = 70;//半径

    /**
     * 获取文字的宽度
     */
    private float lineSize;//文字的宽度

    /**
     * 最终小圆圈的半径
     */
    private float smallRedRadius = strokeWidth * 2;

    /**
     * 相当于添加一个固定的padding值
     */
    private int top = (int) (strokeWidth + smallRedRadius);

    /**
     * 相当于添加一个固定的上方Padding值
     */

    private int left = (int) (strokeWidth + smallRedRadius);

    /**
     * 周长
     */
    private float mAllLength;

    /**
     * 文字
     */
    private String mText;

    /**
     * 文字的边框
     */
    private Rect mBounds;

    /**
     * 画最终的小圆圈
     */
    private Paint mSmallRedPaint;

    /**
     * 终点小圆圈
     */
    private Paint mSmallWhitePaint;

    /**
     * 默认线颜色
     */
    private int normal_line_color = 0x33000000;

    /**
     * 进度条颜色
     */
    private int line_color = 0xffff0000;

    /**
     * 小圈圈外圈颜色
     */
    private int small_outside_circle_color = 0xffff0000;

    /**
     * 小圈圈内圈颜色
     */
    private int small_inside_circle_color = 0xffffffff;

    /**
     * 文字颜色
     */
    private int text_color = 0xff000000;

    private float text_size = 12;
    private int width;
    private int height;
    private Path mPath;
    private int mScreenWidth;
    private int mScreenHeight;
    private float ratioWidth;
    private float ratioHeight;
    private float ratioMetrics;


    public HSProgressButton(Context context) {
        this(context, null);
    }

    public HSProgressButton(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public HSProgressButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setClickable(true);
        //初始化画笔以及文本
        initPaint(context,attrs);
        //准备两个圆，和整体长度，以及绘制
        initPath();
    }

    /**
     * 对控件进行重新绘制
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

//如果宽度模式为精确模式,将父容器指定的宽度赋给View宽，否则View本身计算空间

        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            width = (int) (lineSize + radius * 2 + left *2);
        }

        //如果高度模式为精确模式,将父容器指定的高度赋给View高，否则View本身计算空间
        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            height = (int) (top * 2  + radius * 2);
        }
        setMeasuredDimension(width, height);
    }

    private void initPaint(Context context, AttributeSet attrs) {
        if (attrs != null){
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HSProgressButton);

            if (a.hasValue(R.styleable.HSProgressButton_normal_line_color)){
                normal_line_color = a.getColor(R.styleable.HSProgressButton_normal_line_color, 0x33000000);
            }

            if (a.hasValue(R.styleable.HSProgressButton_pitch_line_color)){
                line_color = a.getColor(R.styleable.HSProgressButton_pitch_line_color,0xffff0000);
            }

            if (a.hasValue(R.styleable.HSProgressButton_small_outside_circle_color)){
                small_outside_circle_color = a.getColor(R.styleable.HSProgressButton_small_outside_circle_color,0xffff0000);
            }

            if (a.hasValue(R.styleable.HSProgressButton_small_inside_circle_color)){
                small_inside_circle_color = a.getColor(R.styleable.HSProgressButton_small_inside_circle_color,0xffffffff);
            }

            if (a.hasValue(R.styleable.HSProgressButton_text_color)){
                text_color = a.getColor(R.styleable.HSProgressButton_text_color,0xff000000);
            }

            if (a.hasValue(R.styleable.HSProgressButton_text)){
                mText =  a.getText(R.styleable.HSProgressButton_text).toString();
            }

            if (a.hasValue(R.styleable.HSProgressButton_button_progress)){
                currentProgress = a.getFloat(R.styleable.HSProgressButton_button_progress,0);
            }

            if (a.hasValue(R.styleable.HSProgressButton_text_size)){
                text_size = a.getFloat(R.styleable.HSProgressButton_text_size,12);
            }

            DisplayMetrics dm = context.getResources().getDisplayMetrics();
            mScreenWidth = dm.widthPixels;
            mScreenHeight = dm.heightPixels;

//以分辨率为720*1080准，计算宽高比值
            ratioWidth = (float) mScreenWidth / 720;
            ratioHeight = (float) mScreenHeight / 1080;
            ratioMetrics = Math.min(ratioWidth, ratioHeight);
            int textSize = Math.round(text_size * ratioMetrics);

            int strokeWidth = Math.round(3 * ratioMetrics);
            this.strokeWidth = strokeWidth;

            int smallRedRadius = Math.round(6 * ratioMetrics);
            this.smallRedRadius = smallRedRadius;
//            top = (int) (strokeWidth + smallRedRadius);
//            left = (int) (strokeWidth + smallRedRadius);
            int top = Math.round((9) * ratioMetrics);
            this.top = top;
            this.left = top;

            //获取布局文件数据，颜色尺寸，进行一个初始化
            mGrayPaint = new Paint();
            mGrayPaint.setColor(normal_line_color);
            mGrayPaint.setStrokeWidth(strokeWidth);
            mGrayPaint.setAntiAlias(true);

            mRedPaint = new Paint();
            mRedPaint.setColor(line_color);//设置颜色
            mRedPaint.setStrokeWidth(strokeWidth);//设置stroke的宽度\
            mRedPaint.setAntiAlias(true);


            mSmallRedPaint = new Paint();
            mSmallRedPaint.setColor(small_outside_circle_color);
            mSmallRedPaint.setStrokeWidth(1);
            mSmallRedPaint.setAntiAlias(true);

            mSmallWhitePaint = new Paint();
            mSmallWhitePaint.setColor(small_inside_circle_color);
            mSmallWhitePaint.setStrokeWidth(1);
            mSmallWhitePaint.setAntiAlias(true);

            textPaint = new Paint();
            textPaint.setColor(text_color);
            textPaint.setTextSize(textSize);
            textPaint.setTextAlign(Paint.Align.CENTER);//从中间开始绘制
            textPaint.setAntiAlias(true);

            //写文字
            mBounds = new Rect();
            textPaint.getTextBounds(mText, 0, mText.length(), mBounds);

            lineSize = (float) (mBounds.width() * 1.0);//设置文字的宽度和进度的宽度相同
            radius = (float) (mBounds.height() * 1.2);//半径最小为文字的高度的一半
        }

    }

    private void initPath() {
        mPath = new Path();
        mOval1 = new RectF(left, top, left + radius * 2, top + radius * 2);
        mOval2 = new RectF(left + lineSize, top, left + 2 * radius + lineSize, top + 2 * radius);

        mProgressPath = new Path();
        mProgressPath.moveTo(left + radius, top);
        mProgressPath.lineTo(left + radius + lineSize, top);
        mProgressPath.moveTo(left + radius, top + 2 * radius);
        mProgressPath.lineTo(left + radius + lineSize, top + 2 * radius);

        mOvalProgress1 = new RectF(left, top, left + radius * 2, top + radius * 2);
        mOvalProgress2 = new RectF(left + lineSize, top, left + 2 * radius + lineSize, top + 2 * radius);

        //计算两个半圆和直线的周长
        calculateLength();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawText(mText, left + (lineSize + radius + radius) / 2, top + radius - mBounds.centerY(), textPaint);

        //设置进度和背景的线是有宽度的
        mGrayPaint.setStyle(Paint.Style.STROKE);
        mRedPaint.setStyle(Paint.Style.STROKE);
        mSmallRedPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mSmallWhitePaint.setStyle(Paint.Style.FILL_AND_STROKE);

        // 设置个新的长方形，扫描测量
        canvas.drawArc(mOval1, 90, 180, false, mGrayPaint);

//        mPath.reset();
        mPath.moveTo(left + radius, top);
        mPath.lineTo(left + radius + lineSize, top);
        mPath.moveTo(left + radius, top + 2 * radius);
        mPath.lineTo(left + radius + lineSize, top + 2 * radius);
        canvas.drawPath(mPath, mGrayPaint);
        // 设置个新的长方形，扫描测量
        canvas.drawArc(mOval2, -90, 180, false, mGrayPaint);

        float smallCircleX;
        float smallCircleY;

        mProgressPath.reset();
        //如果进度大于0就开始绘制进度
        if (currentProgress >= 0 && currentProgress < 1) {
            float length = mAllLength * currentProgress;
            if (length <= lineSize / 2) {//画直线
                mProgressPath.moveTo(left + radius + lineSize / 2, top);
                mProgressPath.lineTo(left + radius +  + lineSize / 2 + length - smallRedRadius, top);
                canvas.drawPath(mProgressPath, mRedPaint);

                smallCircleX = left + radius +  + lineSize / 2 + length;
                smallCircleY = top;

            } else if (length > lineSize / 2 && length <= lineSize / 2 + mPerimeter) {
                mProgressPath.moveTo(left + radius + lineSize / 2, top);
                mProgressPath.lineTo(left + radius + lineSize, top);
                canvas.drawPath(mProgressPath, mRedPaint);
                float ra = length - lineSize / 2;
                float swipe = ra * 180 / mPerimeter;
                float needSubStringSmallredCircle = smallRedRadius * 180 / mPerimeter;
                canvas.drawArc(mOvalProgress2, -90, swipe - needSubStringSmallredCircle, false, mRedPaint);
                //根据弧度计算出
                double swipehudu = Math.toRadians(swipe);
                //计算x值
                smallCircleX = (float) (Math.sin(swipehudu) *radius) + left + radius + lineSize;
                //计算y值
                double acos = Math.cos(swipehudu) * radius;
                smallCircleY = (float) (top + radius - acos);
            } else if (length > lineSize / 2 + mPerimeter && length <= 1.5 * lineSize + mPerimeter) {
                mProgressPath.moveTo(left + radius + lineSize / 2, top);
                mProgressPath.lineTo(left + radius + lineSize, top);
                canvas.drawArc(mOvalProgress2, -90, 180, false, mRedPaint);
                float size = length - lineSize / 2 - mPerimeter;
                mProgressPath.moveTo(left + radius + lineSize, top + 2 * radius);
                mProgressPath.lineTo(left + radius + lineSize - size + smallRedRadius, top + 2 * radius);
                canvas.drawPath(mProgressPath, mRedPaint);
                //获取最后的坐标
                smallCircleX = left + radius + lineSize - size;
                smallCircleY = top + 2 * radius;
            } else if (length > 1.5 * lineSize + mPerimeter && length <= 1.5 * lineSize + mPerimeter * 2) {
                mProgressPath.moveTo(left + radius + lineSize / 2, top);
                mProgressPath.lineTo(left + radius + lineSize, top);
                canvas.drawArc(mOvalProgress2, -90, 180, false, mRedPaint);
                mProgressPath.moveTo(left + radius + lineSize, top + 2 * radius);
                mProgressPath.lineTo(left + radius, top + 2 * radius);
                canvas.drawPath(mProgressPath, mRedPaint);
                float ra = length - mPerimeter - new Float(1.5) * lineSize;
                float swipe = ra * 180 / mPerimeter;
                float needSubStringSmallredCircle = smallRedRadius * 180 / mPerimeter;
                canvas.drawArc(mOvalProgress1, -270, swipe - needSubStringSmallredCircle, false, mRedPaint);
                //根据弧度计算出
                double swipehudu = Math.toRadians(swipe);
                //计算x值
                smallCircleX = (float) (left + radius - (Math.sin(swipehudu) * radius));
                //计算y值
                double acos = Math.cos(swipehudu) * radius;
                smallCircleY = (float) (top + radius + acos);
            } else{
                mProgressPath.moveTo(left + radius + lineSize / 2, top);
                mProgressPath.lineTo(left + radius + lineSize, top);
                canvas.drawArc(mOvalProgress2, -90, 180, false, mRedPaint);
                mProgressPath.moveTo(left + radius + lineSize, top + 2 * radius);
                mProgressPath.lineTo(left + radius, top + 2 * radius);
                canvas.drawArc(mOvalProgress1, -270, 180, false, mRedPaint);
                float bb = length - 2 * mPerimeter - new Float(1.5) * lineSize - smallRedRadius;
                mProgressPath.moveTo(left + radius, top);
                mProgressPath.lineTo(left + radius + bb, top);
                canvas.drawPath(mProgressPath, mRedPaint);
                //获取终点坐标
                smallCircleX = left + radius + bb;
                smallCircleY = top;
            }
            //无论如何根据最后点的坐标画小圆圈
            canvas.drawCircle(smallCircleX,smallCircleY,smallRedRadius,mSmallRedPaint);
//            int textSize = Math.round(5 * ratioMetrics);
            canvas.drawCircle(smallCircleX,smallCircleY,Math.round(3 * ratioMetrics),mSmallWhitePaint);
        }
    }

    private void calculateLength() {
        //计算圆的周长
        mPerimeter = (float) (radius * Math.PI);
        mAllLength = 2 * (mPerimeter + lineSize);
    }

    //设置进度
    public void setCurrentProgress(float currentProgress) {
        if (currentProgress >= 1){
            currentProgress = 1;
        }
        this.currentProgress = currentProgress;
        invalidate();
    }

    /**
     * 执行动画
     * @param listener 监听
     * @param progress 进度
     * @param duration 持续时间
     */
    public void animate(Animator.AnimatorListener listener, final float progress, int duration) {
        // TODO Auto-generated method stub
        ObjectAnimator mProgressBarAnimator = ObjectAnimator.ofFloat(this, "progress", progress);
        mProgressBarAnimator.setDuration(Math.abs((long) (progress*duration)));
        mProgressBarAnimator.addListener(new Animator.AnimatorListener() {

            @Override
            public void onAnimationCancel(final Animator animation) {
            }

            @Override
            public void onAnimationEnd(final Animator animation) {
                setCurrentProgress(progress);
//                setProgress(progress);
            }

            @Override
            public void onAnimationRepeat(final Animator animation) {
            }

            @Override
            public void onAnimationStart(final Animator animation) {
            }
        });
        if (listener != null) {
            mProgressBarAnimator.addListener(listener);
        }
        mProgressBarAnimator.reverse();
        mProgressBarAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(final ValueAnimator animation) {
                setCurrentProgress((Float) animation.getAnimatedValue());
            }
        });

        mProgressBarAnimator.start();
    }

    public void setText(String text){
        mText = text;
        invalidate();
    }

    public void setTextColor(int text_color){
        this.text_color = text_color;
        textPaint.setColor(text_color);
//        invalidate();
    }

}
